﻿using LinqKit;
using Management.Auxiliary;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Data.Entity;

namespace Management.Core.SiliconCutting
{
    public class SiliconCuttingManager : BaseManager<SiliconCutting>
    {
        public Paging<SiliconCutting> FindPageList(Paging<SiliconCutting> pagingSiliconCutting, int? SiliconCuttingID, DateTime start, DateTime end, SiliconCutting sc, int? order)
        {
            //查询表达式
            var _where = PredicateBuilder.New<SiliconCutting>(true);
            if (SiliconCuttingID != null && SiliconCuttingID > 0) _where = _where.And(u => u.SiliconCuttingID == SiliconCuttingID);
            if (start != null)
            {                
                _where = _where.And(u => u.CuttingDate >= start);
            }
            if (end != null)
            {
                _where = _where.And(u => u.CuttingDate <= end);
            }
            if (sc != null)
            {
                #region 硅片切割的检索条件,真特么多。。。硅片行业不容易啊！
                if(sc.SiliconCuttingID > 0)                
                    _where = _where.And(u => u.SiliconCuttingID == sc.SiliconCuttingID);
                if (sc.BottomMaterialLength > 0)
                    _where = _where.And(u => u.BottomMaterialLength == sc.BottomMaterialLength);
                if (sc.BreakedID > 0)
                    _where = _where.And(u => u.BreakedID == sc.BreakedID);
                if (!string.IsNullOrEmpty(sc.Checker))
                    _where = _where.And(u => u.Checker == sc.Checker);
                if (!string.IsNullOrEmpty(sc.CleaningEquipmentNum))
                    _where = _where.And(u => u.CleaningEquipmentNum == sc.CleaningEquipmentNum);
                if (sc.CuttingBlock > 0)
                    _where = _where.And(u => u.CuttingBlock == sc.CuttingBlock);
                if (sc.CuttingID > 0)
                    _where = _where.And(u => u.CuttingID == sc.CuttingID);
                if (sc.CuttingLength > 0)
                    _where = _where.And(u => u.CuttingLength == sc.CuttingLength);
                if (!string.IsNullOrEmpty(sc.CuttingNum))
                    _where = _where.And(u => u.CuttingNum == sc.CuttingNum);
                if (sc.CuttingSpecification > 0)
                    _where = _where.And(u => u.CuttingSpecification == sc.CuttingSpecification);
                if (sc.CuttingThickness > 0)
                    _where = _where.And(u => u.CuttingThickness == sc.CuttingThickness);
                if (!string.IsNullOrEmpty(sc.CuttingType))
                    _where = _where.And(u => u.CuttingType == sc.CuttingType);
                if (sc.DebrisWeight > 0)
                    _where = _where.And(u => u.DebrisWeight == sc.DebrisWeight);
                if (!string.IsNullOrEmpty(sc.EmployeeNum))
                    _where = _where.And(u => u.EmployeeNum == sc.EmployeeNum);
                if (sc.EquipmentFileID > 0)//这个可能要变动
                    _where = _where.And(u => u.EquipmentFileID == sc.EquipmentFileID);
                if (sc.GuideNum > 0)
                    _where = _where.And(u => u.GuideNum == sc.GuideNum);
                if (!string.IsNullOrEmpty(sc.Handler))
                    _where = _where.And(u => u.Handler == sc.Handler);
                //if (sc.IsBreaked >= 0)
                //    _where = _where.And(u => u.IsBreaked == sc.IsBreaked);
                //if (sc.IsCheck >= 0)
                //    _where = _where.And(u => u.IsCheck == sc.IsCheck);
                //if (sc.IsIncludedAssessment >= 0)
                //    _where = _where.And(u => u.IsIncludedAssessment == sc.IsIncludedAssessment);
                //if (sc.IsScrap >= 0)
                //    _where = _where.And(u => u.IsScrap == sc.IsScrap);
                //if (sc.IsSpotCheck >= 0)
                //    _where = _where.And(u => u.IsSpotCheck == sc.IsSpotCheck);
                //if (sc.IsTest >= 0)
                //    _where = _where.And(u => u.IsTest == sc.IsTest);
                if (sc.LevelOneCount > 0)
                    _where = _where.And(u => u.LevelOneCount == sc.LevelOneCount);
                if (sc.LevelOneTheoreticalCount > 0)
                    _where = _where.And(u => u.LevelOneTheoreticalCount == sc.LevelOneTheoreticalCount);
                if (sc.LevelThreeCount > 0)
                    _where = _where.And(u => u.LevelThreeCount == sc.LevelThreeCount);
                if (sc.LevelTwoCount > 0)
                    _where = _where.And(u => u.LevelTwoCount == sc.LevelTwoCount);
                if (!string.IsNullOrEmpty(sc.Pre_CleaningEquipmentNum))
                    _where = _where.And(u => u.Pre_CleaningEquipmentNum == sc.Pre_CleaningEquipmentNum);
                if (sc.PulpDensityEnd > 0)
                    _where = _where.And(u => u.PulpDensityEnd == sc.PulpDensityEnd);
                if (sc.PulpDensityStart > 0)
                    _where = _where.And(u => u.PulpDensityStart == sc.PulpDensityStart);
                if (sc.PulpUpdateCount > 0)
                    _where = _where.And(u => u.PulpUpdateCount == sc.PulpUpdateCount);
                if (sc.QualifiedCount > 0)
                    _where = _where.And(u => u.QualifiedCount == sc.QualifiedCount);
                if (!string.IsNullOrEmpty(sc.QualifiedRate))
                    _where = _where.And(u => u.QualifiedRate == sc.QualifiedRate);
                if (!string.IsNullOrEmpty(sc.Remark))
                    _where = _where.And(u => u.Remark == sc.Remark);
                if (sc.SiliconCarbideID > 0)
                    _where = _where.And(u => u.SiliconCarbideID == sc.SiliconCarbideID);
                if (sc.SlotPitch > 0)
                    _where = _where.And(u => u.SlotPitch == sc.SlotPitch);
                if (sc.SpotCheckCount > 0)
                    _where = _where.And(u => u.SpotCheckCount == sc.SpotCheckCount);
                if (!string.IsNullOrEmpty(sc.SpotChecker))
                    _where = _where.And(u => u.SpotChecker == sc.SpotChecker);
                if (!string.IsNullOrEmpty(sc.SpotCheckRemark))
                    _where = _where.And(u => u.SpotCheckRemark == sc.SpotCheckRemark);
                if (sc.SpotCheckUnqualifiedCount > 0)
                    _where = _where.And(u => u.SpotCheckUnqualifiedCount == sc.SpotCheckUnqualifiedCount);
                if (sc.SteelWireID > 0)
                    _where = _where.And(u => u.SteelWireID == sc.SteelWireID);
                if (sc.SumCount > 0)
                    _where = _where.And(u => u.SumCount == sc.SumCount);
                if (sc.SuspensionID > 0)
                    _where = _where.And(u => u.SuspensionID == sc.SuspensionID);
                if (sc.TeamID > 0)
                    _where = _where.And(u => u.TeamID == sc.TeamID);
                if (sc.UnqualifiedCount > 0)
                    _where = _where.And(u => u.UnqualifiedCount == sc.UnqualifiedCount);
                if (sc.WorkshopID > 0)
                    _where = _where.And(u => u.WorkshopID == sc.WorkshopID);
                #endregion
            }
            bool flag = false;//标记是否需要重新检索所有变量，根据检索条件变化来判断
            if (RedisHelper.Get<SiliconCutting>("SiliconCuttingModel") == null || RedisHelper.Get<string>("start") == null || RedisHelper.Get<string>("end") == null)
            {
                RedisHelper.Set<SiliconCutting>("SiliconCuttingModel", sc, DateTime.Now.AddHours(1) - DateTime.Now);
                RedisHelper.Set<string>("start", start.ToString(), DateTime.Now.AddHours(1) - DateTime.Now);
                RedisHelper.Set<string>("end", end.ToString(), DateTime.Now.AddHours(1) - DateTime.Now);
            }
            else
            {
                SiliconCutting oldsc = RedisHelper.Get<SiliconCutting>("SiliconCuttingModel");
                DateTime oldstart = DateTime.Parse(RedisHelper.Get<string>("start"));
                DateTime oldend = DateTime.Parse(RedisHelper.Get<string>("end"));
                if (oldstart != start || oldend != end || oldsc != sc)
                {
                    flag = true;
                    RedisHelper.DelKey("start");
                    RedisHelper.DelKey("end");
                    RedisHelper.DelKey("SiliconCuttingModel");
                }
            }
            //排序
            OrderParam _orderParam;
            switch (order)
            {
                case 0://ID升序
                    _orderParam = new OrderParam() { PropertyName = "SiliconCuttingID", Method = OrderMethod.ASC };
                    break;
                case 1://ID降序
                    _orderParam = new OrderParam() { PropertyName = "SiliconCuttingID", Method = OrderMethod.DESC };
                    break;
                case 2://创建时间降序
                    _orderParam = new OrderParam() { PropertyName = "Created_at", Method = OrderMethod.ASC };
                    break;
                case 3://创建时间升序
                    _orderParam = new OrderParam() { PropertyName = "Created_at", Method = OrderMethod.DESC };
                    break;
                case 4://修改时间升序
                    _orderParam = new OrderParam() { PropertyName = "Updated_at", Method = OrderMethod.ASC };
                    break;
                case 5://修改时间降序
                    _orderParam = new OrderParam() { PropertyName = "Updated_at", Method = OrderMethod.DESC };
                    break;
                default://ID降序
                    _orderParam = new OrderParam() { PropertyName = "SiliconCuttingID", Method = OrderMethod.DESC };
                    break;
            }

            pagingSiliconCutting.Items = Repository.FindPageList(pagingSiliconCutting.PageSize, pagingSiliconCutting.PageIndex, out pagingSiliconCutting.TotalNumber, _where, _orderParam).ToList();
            
            if (RedisHelper.Get<List<System.Collections.Hashtable>>("ht_virables") == null)
            {
                List<Hashtable> _virables = new List<Hashtable>();
                _virables.Add(Virables(_where));
                RedisHelper.Set<List<System.Collections.Hashtable>>("ht_virables", _virables, DateTime.Now.AddHours(1) - DateTime.Now);
            }
            else
            {                
                if (flag)
                {
                    RedisHelper.DelKey("ht_virables");
                    List<Hashtable> _virables = new List<Hashtable>();
                    _virables.Add(Virables(_where));                    
                    RedisHelper.Set<List<System.Collections.Hashtable>>("ht_virables", _virables, DateTime.Now.AddHours(1) - DateTime.Now);
                }
            }
            
            //pagingSiliconCutting.Virables = _virables;
            return pagingSiliconCutting;
        }

        //得到一堆变量
        public Hashtable Virables(System.Linq.Expressions.Expression<Func<SiliconCutting, bool>> where)
        {
            Hashtable ht = new Hashtable();
            var result = Repository.FindList(where);
            //切割次数
            var cuttingCount = result.Count();
            ht.Add("cuttingCount", cuttingCount);
            //断线次数
            var breakedCount = result.Where(u => u.IsBreaked > 0).Count();
            ht.Add("breakedCount", breakedCount);
            //切割硅块数量
            var siliconBlockCount = result.Sum(u => u.CuttingBlock);
            ht.Add("siliconBlockCount", siliconBlockCount);
            //总有效切割长度
            var siliconLength = result.Sum(u => u.CuttingLength);
            ht.Add("siliconLength", siliconLength);
            //平均有效切割长度
            var aveSiliconLength = Math.Round(siliconLength / siliconBlockCount, 2);
            ht.Add("aveSiliconLength", aveSiliconLength);
            //硅块切割长度(这个原测试库的view里不包含这个字段，怀疑是和正式库不一样)
            var sumSiliconCuttingLength = 0;
            ht.Add("sumSiliconCuttingLength", sumSiliconCuttingLength);
            //平均切割硅块长度(原因同上)；
            var aveSiliconCuttingLength = 0;
            ht.Add("aveSiliconCuttingLength", aveSiliconCuttingLength);
            //硅片切割数量
            var sumCuttingSiliconPiaceCount = result.Sum(u => u.SumCount);
            ht.Add("sumCuttingSiliconPiaceCount", sumCuttingSiliconPiaceCount);
            //硅片合格数量
            var sumQualifiedCount = result.Sum(u => u.QualifiedCount);
            ht.Add("sumQualifiedCount", sumQualifiedCount);
            //硅片合格率
            var sumQualifiedRate = Math.Round(sumQualifiedCount / (decimal)sumCuttingSiliconPiaceCount, 2);
            ht.Add("sumQualifiedRate", sumQualifiedRate);
            //A级品率
            var AQualifiedRate = Math.Round(result.Sum(u => u.LevelOneCount) / (decimal)sumQualifiedCount, 2);
            ht.Add("AQualifiedRate", AQualifiedRate);
            //平均单锭出片数
            var aveSingleCount = Math.Round(sumCuttingSiliconPiaceCount / (decimal)siliconBlockCount, 2);
            ht.Add("aveSingleCount", aveSingleCount);
            //线锯开机率
            var lineStartRate = 0;
            ht.Add("lineStartRate", lineStartRate);
            //----这里开始下面的变量是构造合格率表所需要的,图省事，放一个哈希里了，后续开发人员可以进行改进一下^_^——By Tony---------//
            
            #region 野蛮写法，但能确保正确
            var unQualifiedEnglistNames = result.Where(u => u.SliceQuality.WaterQuality.isQualified == 0).GroupBy(u => u.SliceQuality.WaterQuality.EnglishName).Select(i => i.Key);
            
            foreach (var unQualifiedEnglistName in unQualifiedEnglistNames)
            {
                ManagementContext mc = new ManagementContext();
                var _where = where;
                _where = _where.And(u => u.SliceQuality.WaterQuality.isQualified == 0 && u.SliceQuality.WaterQuality.EnglishName == unQualifiedEnglistName);
                var a = mc.SiliconCutting.Where(_where).Sum(u => u.SliceQuality.Number);
                ht.Add(unQualifiedEnglistName, a);
                ht.Add(unQualifiedEnglistName + "Rate", Math.Round(a / (decimal)sumCuttingSiliconPiaceCount, 2));
                mc.Dispose();
            }
            var QualifiedEnglistNames = result.Where(u => u.SliceQuality.WaterQuality.isQualified == 1).GroupBy(u => u.SliceQuality.WaterQuality.EnglishName).Select(i => i.Key);
            
            foreach (var QualifiedEnglistName in QualifiedEnglistNames)
            {
                ManagementContext mc = new ManagementContext();
                var _where = where;
                _where = _where.And(u => u.SliceQuality.WaterQuality.isQualified == 1 && u.SliceQuality.WaterQuality.EnglishName == QualifiedEnglistName);
                var a = mc.SiliconCutting.Where(_where).Sum(u => u.SliceQuality.Number);
                ht.Add(QualifiedEnglistName, a);
                ht.Add(QualifiedEnglistName + "Rate", Math.Round(a / (decimal)sumCuttingSiliconPiaceCount, 2));
                mc.Dispose();
            }
            #endregion
            
            return ht;
        }

    }
}
